package com.suoluo.zenadmin.controllers.portal.account;

import java.io.IOException;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import net.paoding.rose.web.Invocation;
import net.paoding.rose.web.annotation.Param;
import net.paoding.rose.web.annotation.Path;
import net.paoding.rose.web.annotation.rest.Get;
import net.paoding.rose.web.annotation.rest.Post;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import weibo4j.Account;
import weibo4j.Oauth;
import weibo4j.Timeline;
import weibo4j.Users;
import weibo4j.Weibo;
import weibo4j.http.AccessToken;
import weibo4j.http.ImageItem;
import weibo4j.model.User;
import weibo4j.model.WeiboException;
import weibo4j.org.json.JSONException;

import com.qq.connect.QQConnectException;
import com.qq.connect.api.OpenID;
import com.qq.connect.api.qzone.Share;
import com.qq.connect.api.qzone.UserInfo;
import com.qq.connect.javabeans.GeneralResultBean;
import com.qq.connect.javabeans.qzone.UserInfoBean;
import com.qq.connect.javabeans.weibo.WeiboBean;
import com.suoluo.zenadmin.common.CommonResp;
import com.suoluo.zenadmin.common.StringUtil;
import com.suoluo.zenadmin.common.UBB;
import com.suoluo.zenadmin.common.config.SystemConfigHolder;
import com.suoluo.zenadmin.controllers.JSONInterceptor.JSON;
import com.suoluo.zenadmin.oss.OSSService;
import com.suoluo.zenadmin.service.account.AccountService;
import com.suoluo.zenadmin.service.dest.DestService;
import com.suoluo.zenadmin.service.hotel.HotelService;
import com.suoluo.zenadmin.service.news.NewsService;
import com.suoluo.zenadmin.vo.account.AccountVO;
import com.suoluo.zenadmin.vo.account.OpenAccountVO;
import com.suoluo.zenadmin.vo.dest.DestFeature2VO;
import com.suoluo.zenadmin.vo.dest.DestFeatureItem2VO;
import com.suoluo.zenadmin.vo.dest.DestVO;
import com.suoluo.zenadmin.vo.hotel.Hotel2VO;
import com.suoluo.zenadmin.vo.hotel.HotelResource2VO;
import com.suoluo.zenadmin.vo.news.News2VO;
import com.suoluo.zenadmin.vo.share.AuthedVO;
import com.suoluo.zenadmin.vo.share.ShareVO;

@Path("")
public class AccountController {
	private static final Log logger = LogFactory.getLog(AccountController.class);
	
	@Resource(name="accountService")
	private AccountService accountService;
	
	@Resource(name="newsService")
	private NewsService newsService;
	
	@Resource(name="destService")
	private DestService destService;
	
	@Resource(name="hotelService")
	private HotelService hotelService;
	
	@Resource(name="ossService")
	private OSSService ossService;
	
	/**
	 * 新浪平台
	 */
	public static final int OPEN_TYPE_SINA = 1;

	/**
	 * 腾讯
	 */
	public static final int OPEN_TYPE_TENCENT = 2;
	
	/**
	 * 分享平台的名称
	 */
	public static final String OPEN_TYPE_NAME_QZONE = "qzone";

	/**
	 * 新闻
	 */
	public static final int SHARE_TYPE_NEWS = 1;
	/**
	 * 目的地
	 */
	public static final int SHARE_TYPE_DEST = 2;
	/**
	 * 特色
	 */
	public static final int SHARE_TYPE_FEATURE = 3;
	/**
	 * 特色项
	 */
	public static final int SHARE_TYPE_FEATURE_ITEM = 4;
	/**
	 * 酒店
	 */
	public static final int SHARE_TYPE_HOTEL = 5;

	/**
	 * 酒店资源的分享
	 */
	public static final int SHARE_TYPE_HOTEL_RES = 6;

	public String test(){
		return "newstest";
	}
	@Get("login")
	public String login(){
		return "login";
	}
	
	@Get("sina")
	public String sina(){
		return "sina";
	}
	
	@Get("qq")
	public String qq(){
		return "qq";
	}
	
	@Get("logout")
	public String logout(Invocation inv){
		if (LoginManager.getInstance().isLogined(inv)){
			LoginManager.getInstance().logout(inv);
			//重定向到首页，用来删除客户端的cookie信息
			return "r:" + inv.getRequestPath().getCtxpath()+"/";
		}else{
			//如果没有登录，则跳转到登录页面
			return "login";
		}
	}
	
	/**
	 * 
	 * @param inv 当前请求的执行上下文对象
	 * @param shareType 分享的类型
	 * @param openType 开放平台类型
	 * @param dataId 数据的编号
	 * @param oriUrl 分享的原始页面
	 * @param openTypeName 分享类型的名称
	 * @return CommonResp 分享是否成功
	 */
	@JSON
	@Post("share")
	public Object share(Invocation inv,
			@Param("shareType")int shareType,
			@Param("openType") int openType,
			@Param("dataId") int dataId,
			@Param("ori_url") String oriUrl,
			@Param("openTypeName") String openTypeName){
		HttpServletRequest request = inv.getRequest();
		//是否登录
		if (!LoginManager.getInstance().isLogined(inv)) {
			return unauth(request, openType, oriUrl);
		}

		if (shareType == 0 || openType == 0 || dataId == 0) {
			return shareFail("分享数据缺失，请见谅!");
		} else {
			//验证是否有该类型的账号授权
			AccountVO account = LoginManager.getInstance().getLoginInfo(inv);
			OpenAccountVO openAccount = account.getOpenAccount(openType);
			if (openAccount == null){
				return unauth(request, openType, oriUrl);
			}
			
			// 获取分享的内容数据
			ShareVO shareVO = queryShareData(shareType, oriUrl, dataId);
			// 没有该类型的分享
			if (shareVO == null) {
				logger.error("share data is null,dataid = " + dataId
						+ ",shareType=" + shareType);
				return shareFail("暂不支持该类型的分享!");
			}
			// 发布一条新浪微薄
			if (openType == OPEN_TYPE_SINA) {
				return sendSinaWeibo(request,openAccount, shareVO);
			} else if (openType == OPEN_TYPE_TENCENT && OPEN_TYPE_NAME_QZONE.equals(openTypeName)) {
				//分享到QQ空间
				return sendQZone(openAccount, shareVO);
			}  else if (openType == OPEN_TYPE_TENCENT) {
				// 发布一条腾讯微薄
				return sendTencentWeibo(openAccount, shareVO);
			}else {
				logger.error("Unsupport the openType,openType=" + openType);
				return shareFail("暂不支持该类型的分享!");
			}
		}
	}
	
	private CommonResp sendSinaWeibo(HttpServletRequest request,OpenAccountVO openAccount, ShareVO shareVO) {
		try {
			Timeline tl = new Timeline();
			Weibo weibo = new Weibo();
			weibo.setToken(openAccount.getToken());// access_token
			String data = java.net.URLEncoder.encode(shareVO.getContent()+shareVO.getOriurl(),
					"utf-8");
			ImageItem pic = new ImageItem("pic", ossService.readImage(shareVO.getImgUrl()));
			tl.UploadStatus(weibo, data, pic);
			return shareSuccess("新浪微博分享成功");
		} catch (WeiboException e) {
			// expire_token 失效,重定向到授权页面
			logger.error("fail to share weibo,errorCode=" + e.getErrorCode()
					+ ",error=" + e.getError(), e);
			if (e.getErrorCode() == 21327 || e.getErrorCode() == 21315) {
				return unauth(request, OPEN_TYPE_SINA, shareVO.getOriurl());
			} else {
				return shareFail("分享到新浪微博失败,请稍后分享，对您造成的不便非常抱歉!");
			}
			

		} catch (IOException e) {
			logger.error("fail to read img [" + shareVO.getImgUrl() + "]", e);
			return shareFail("分享到新浪微博,图片分享失败,请稍后分享，对您造成的不便非常抱歉!");
		}
	}

	private CommonResp sendTencentWeibo(OpenAccountVO openAccount, ShareVO shareVO) {

		String openID = openAccount.getOpenId();
		String accessToken = openAccount.getToken();
		com.qq.connect.api.weibo.Weibo weibo = new com.qq.connect.api.weibo.Weibo(
				accessToken, openID);
		// 0x2-图片数据大小错误则报错
		// 0x4-检查图片格式不支持则报错
		// 0x8-上传图片失败则报错
		// 0x20-微博内容长度超过140字则报错
		try {
			byte[] picData = ossService.readImage(shareVO.getImgUrl());
			WeiboBean weiboBean = weibo.addPicWeibo(shareVO.getContent()+shareVO.getOriurl(), picData);
			if (weiboBean.getRet() == 0) {
				return shareSuccess("腾讯微博分享成功");
			} else {
				logger.error("fail to send weibo to tencent,resutl="
						+ weiboBean);
				return shareFail("分享到腾讯微博失败,请稍后分享，对您造成的不便非常抱歉!");
			
			}
		} catch (Exception e) {
			logger.error("fail to send weibo to tencent", e);
			return shareFail("分享到腾讯微博失败,请稍后分享，对您造成的不便非常抱歉!");
			
		}
	}
	
	private CommonResp sendQZone(OpenAccountVO openAccount, ShareVO shareVO) {
		
		String openID = openAccount.getOpenId();
		String accessToken = openAccount.getToken();
		Share qzoneShare = new Share(accessToken, openID);
		// 0x2-图片数据大小错误则报错
		// 0x4-检查图片格式不支持则报错
		// 0x8-上传图片失败则报错
		// 0x20-微博内容长度超过140字则报错
		try {
//			byte[] picData = FileUtils.readFile(request, shareVO.getImgUrl());
			String domainName = SystemConfigHolder.getDomainName();
			String imageUrl = domainName + SystemConfigHolder.getUploadImageRoot() + shareVO.getImgUrl();
			GeneralResultBean result = qzoneShare.addShare(shareVO.getTitle(), shareVO.getOriurl(),
					"禅境旅行", domainName,"comment=奢华旅行度假指南-为追求完美的旅行者发现纯净、自然、宁静的避世之地 ",
					"summary="+shareVO.getContent(),
					"images="+imageUrl);
			if (result.getRet() == 0) {
				return shareSuccess("QQ空间分享成功");
			} else {
				if (result.getRet() == 100031){
					return shareFail("QQ空间分享的权限正在申请中，对您造成的不便非常抱歉!");
				}else {
					logger.error("fail to send weibo to tencent,resutl="
							+ result);
					return shareFail("分享到QQ空间失败,请稍后分享，对您造成的不便非常抱歉!");
					
				}
			}
		} catch (Exception e) {
			logger.error("fail to send weibo to qzone", e);
			return shareFail( "QQ空间分享失败,请稍后分享，对您造成的不便非常抱歉!");
		}
	}


	private CommonResp unauth(HttpServletRequest request,int openType,String oriUrl){
		CommonResp resp = new CommonResp();
		resp.setResultCode("222222222");
		// 记录用户点击分享的页面，用户授权后需要跳转到原始页面，重新进行内容分享
		request.getSession().setAttribute("ori_url", oriUrl);
		// 需要根据不同的平台类型，跳转到不同的平台授权页面
		if (OPEN_TYPE_SINA == openType){
			resp.setResultMsg(request.getContextPath()+"/account/sina");
		}else if(OPEN_TYPE_TENCENT == openType){
			resp.setResultMsg(request.getContextPath()+"/account/qq");
		}
		return resp;
	}
	
	private CommonResp shareFail(String content){
		CommonResp resp = new CommonResp();
		resp.setResultCode(CommonResp.FAIL_CODE);
		resp.setResultMsg(content);
		return resp;
	}
	
	private CommonResp shareSuccess(String content){
		CommonResp resp = new CommonResp();
		resp.setResultCode(CommonResp.SUCCESS_CODE);
		resp.setResultMsg(content);
		return resp;
	}
	/**
	 * 获取分享的数据
	 * 
	 * @param shareType
	 *            分享的类型(新闻，目的地，酒店,目的地特色，目的地特色项)
	 * @param oriurl
	 *            用户分享的界面
	 * @return ShareVO 分享的数据
	 */
	private ShareVO queryShareData(int shareType, String oriurl, int dataId) {
		String content = null;
		String imgUrl = null;
		String title = null;
		if (SHARE_TYPE_NEWS == shareType) {
//			NewsPOJO news = newsService.queryNewsById(dataId);
			News2VO news = newsService.findNewsById(dataId);
			content = news.getContent();
			title = news.getName();
			imgUrl = news.getSource();
		} else if (SHARE_TYPE_DEST == shareType) {
			DestVO dest = destService.findDestById(dataId);
			content = dest.getContent();
			title = dest.getName();
			imgUrl = dest.getSource();
		} else if (SHARE_TYPE_FEATURE == shareType) {
			DestFeature2VO feature = destService.findDestFeatureById(dataId);
			content = feature.getContent();
//			DestFeatureCategoryPOJO category = destService.findDestFeatureCategoryById(feature.getFeatureCategoryId());
			title = feature.getZhname();
			imgUrl = feature.getSource();
		} else if (SHARE_TYPE_FEATURE_ITEM == shareType) {
			DestFeatureItem2VO item = destService.findFeatureItemById(dataId);
			content = item.getContent();
			title = item.getName();
			imgUrl = item.getSource();
		} else if (SHARE_TYPE_HOTEL == shareType) {
			Hotel2VO hotel = hotelService.findHotelById(dataId);
			content = hotel.getContent();
			imgUrl = hotel.getSource();
		} else if (SHARE_TYPE_HOTEL_RES == shareType) {
			HotelResource2VO resource = hotelService.findHotelResourceById(dataId);
			content = resource.getContent();
			title = resource.getName();
//			// 资源的图片，需要截取掉小图片前面的mini前缀，上传大图
			imgUrl = resource.getSource();
//			if (fileName != null) {
//				fileName = fileName.replace("mini/", "");;
//			}
//			imgUrl = fileName;
		} else {
			return null;
		}
		String data = UBB.clear(content);
		if (data.length() > 130) {
			data = data.substring(0, 125);
		}
		ShareVO shareVO = new ShareVO();
		shareVO.setContent(data);
		shareVO.setTitle(title);
		shareVO.setImgUrl(imgUrl);
		shareVO.setOriurl(oriurl);
		return shareVO;
	}
	
//	public static void main(String[] args) {
//		String one = "web/mini/8ed9a3a802e38d37869f57dfdeee77fa.jpg";
//		String two = one.replace("mini/", "");
//		System.out.println("截取路径："+two);
//	}
	
	@Get("auth/qq")
	public String authQQ(Invocation inv) throws QQConnectException {
		String qqLoginUrl = new com.qq.connect.oauth.Oauth()
				.getAuthorizeURL(inv.getRequest());
		return "r:" + qqLoginUrl;
	}
	
	@Get("auth/sina")
	public String authSina() throws WeiboException{
		Oauth oauth = new Oauth();
		String authUrl = oauth.authorize("code", 1);
		return "r:"+authUrl;
	}
	
	@Get("authed/sina")
	public String authedSina(Invocation inv,@Param("code") String code) throws WeiboException, JSONException{
		//如果取消，则跳转到首页
		if (code == null){
			logger.error("fail to authed sina,code is null");
			return "r:" + inv.getRequestPath().getCtxpath()+"/";
		}
		Oauth oauth = new Oauth();
		Weibo weibo = new Weibo();
		AccessToken accessToken = oauth.getAccessTokenByCode(weibo, code);
		String token = accessToken.getAccessToken();
		logger.debug("auth token[" + token +"]");
		weibo.setToken(token);
		// 获取用户信息UID
		Account am = new Account();
		weibo4j.org.json.JSONObject juid = am.getUid(weibo);
		// 获取微薄的账号编号
		String uid = juid.getString("uid");// "2748393372";//
				
		
		AuthedVO authedVO = new AuthedVO();
		authedVO.setOpenType(OPEN_TYPE_SINA);
		authedVO.setOpenId(uid);
		int expireIn = Integer.parseInt(accessToken.getExpireIn());
		authedVO.setExpireIn(expireIn);
		authedVO.setToken(token);
		Users um = new Users();
		User user = um.showUserById(weibo, uid);
		authedVO.setScreenName(user.getName());
		authedVO.setHead(user.getProfileImageUrl());
		if (user.getGender().equals("m")) {
			authedVO.setGender(1);
		} else if (user.getGender().equals("f")) {
			authedVO.setGender(2);
		} else {
			authedVO.setGender(0);
		}
		authedVO.setDomainName(user.getUserDomain());
		
		//获取当前登录的用户信息
		AccountVO account = LoginManager.getInstance().getLoginInfo(inv);
		//授权
		return authed(inv, account, authedVO);
	
	}
	
	@Get("authed/qq")
	public String authedQQ(Invocation inv) throws QQConnectException {
		// 获取用户确认授权后的回调证书信息
		HttpServletRequest request = inv.getRequest();
		com.qq.connect.javabeans.AccessToken accessTokenObj = (new com.qq.connect.oauth.Oauth())
				.getAccessTokenByRequest(request);

		String token = accessTokenObj.getAccessToken();
		if (StringUtil.isEmpty(token)) {
			// // 我们的网站被CSRF攻击了或者用户取消了授权
			// // 做一些数据统计工作
			logger.error("我们的网站被CSRF攻击了或者用户取消了授权");
			return "a:auth/qq";
		}
		OpenID openIDObj = new OpenID(token);
		String openID = openIDObj.getUserOpenID();
		UserInfo qzoneUserInfo = new UserInfo(token, openID);
		UserInfoBean userInfoBean = qzoneUserInfo.getUserInfo();
		// // 授权失败
		if (userInfoBean.getRet() != 0) {
			logger.error("fail to read qzone user info");
			return "a:auth/qq";
		}
		
		AuthedVO authedVO = new AuthedVO();
		authedVO.setOpenType(OPEN_TYPE_TENCENT);
		authedVO.setOpenId(openID);
		authedVO.setExpireIn(accessTokenObj.getExpireIn());
		authedVO.setToken(token);
		authedVO.setScreenName(userInfoBean.getNickname());
		authedVO.setHead(userInfoBean.getAvatar().getAvatarURL30());
		authedVO.setDomainName("http://www.qq.com");
		String sex = userInfoBean.getGender();
		if ("男".equals(sex)) {
			authedVO.setGender(1);
		} else {
			authedVO.setGender(2);
		}
		//获取当前的授权信息
		AccountVO account = LoginManager.getInstance().getLoginInfo(inv);
		//授权
		return authed(inv, account, authedVO);
		
	}
	
	private String authed(Invocation inv,AccountVO account,AuthedVO authedVO){
		// 更新授权信息
		account = accountService.updateAuthed(account, authedVO);
		LoginManager.getInstance().login(inv, account);
		HttpSession session = inv.getRequest().getSession();
		String oriurl = (String) session.getAttribute("ori_url");
		if (!StringUtil.isEmpty(oriurl)) {
			session.removeAttribute("ori_url");
			return "r:" + oriurl;
		} else {
			//首页
			return "r:" + inv.getRequestPath().getCtxpath()+"/";
		}
	}

}
